import { Provide, Inject } from '@midwayjs/core';
import { Repository } from 'typeorm';
import { OtaTask } from '../../entity/firmware/ota_task.entity';
import { DictDataEntity } from '@entity/system/dictData.entity';
import { DictDataService } from '@service/system/dictData.service';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { v4 as uuidv4 } from 'uuid';
import { Gateway } from '@entity/firmware/gateway.entity';
import { Wristband } from '@entity/firmware/wristband.entity';
import { resBuild } from '@utils/resBuild';
import { GatewayWristband } from '@entity/firmware/gateway_wristband.entity';
import { ActionLogOta } from '@entity/firmware/actionLogOta.entity';
// import { action_enum } from '@entity/enums';

@Provide()
export class OtaTaskService {
  @Inject()
  dictDataService: DictDataService;
  @InjectEntityModel(OtaTask)
  otaTask: Repository<OtaTask>;
  @InjectEntityModel(DictDataEntity)
  dictDataRepo: Repository<DictDataEntity>;
  @InjectEntityModel(Gateway)
  gatewayRepo: Repository<Gateway>;
  @InjectEntityModel(Wristband)
  wristbandRepo: Repository<Wristband>;
  @InjectEntityModel(GatewayWristband)
  gatewayWristbandRepo: Repository<GatewayWristband>;
  @InjectEntityModel(ActionLogOta)
  actionLogOtaRepository: Repository<ActionLogOta>;


  async findTaskById(taskId: string) {
    return await this.otaTask.findOne({ 
      where: { 
        id: taskId 
      } 
    });
  }

  // **添加 OTA 操作任务**
  async createOtaTask(data: Partial<OtaTask>) {
    console.log('createOtaTask', data);
    let { id, firmwareid, firmwareid_1, gw_mac, wb_mac, full, gw_full, wb_full, force, updateMode, remain, duration, wb_count, path } = data;
    // **1. 确保 firmwareid 是字符串**
    const firmwareIdStr = firmwareid ? firmwareid.toString() : null;
    let firmwareId1Str = null;
    // 2. 如果 firmwareid_1 存在, 确保 firmwareid_1 是字符串**
    if (firmwareid_1) {
      firmwareId1Str = firmwareid_1 ? firmwareid_1.toString() : null;
    }
    // **2. 处理 gw_mac 和 wb_mac**
    if (gw_full) {
      const gwList = await this.gatewayRepo.find({ select: ['mac'] });
      gw_mac = gwList.map(item => item.mac).join(',');
    }
    if (wb_full) {
      const wbList = await this.wristbandRepo.find({ select: ['mac'] });
      wb_mac = wbList.map(item => item.mac).join(',');
    }
    let gwMacList = [];
    let wbMacList = [];

    // 转换 gw_mac 和 wb_mac 为数组，去除空字符串并去重
    const regex = /[，,]/g;
    // gw_mac 中可能包含逗号分隔的多个 MAC 地址
    gw_mac = gw_mac.replace(regex, ','); // 替换为英文逗号
    if (gw_mac.includes(',')) {
      gwMacList = gw_mac ? [...new Set(gw_mac.split(',').filter(mac => mac.trim() !== ''))] : [];
    } else {
      gwMacList = [gw_mac]
    }
    // wb_mac 中可能包含逗号分隔的多个 MAC 地址
    // 如果是逗号分隔的字符串，转换为数组并去重
    // 这里使用了一个正则表达式来匹配中文和英文逗号
    wb_mac = wb_mac.replace(regex, ','); // 替换为英文逗号
    // console.log('wb_mac 是否有逗号', wb_mac.includes(','))
    // console.log('wb_mac 结果', wb_mac)
    if (wb_mac.includes(',')) {
      // console.log('wb_mac 包含逗号')
      wbMacList = wb_mac ? [...new Set(wb_mac.split(',').filter(mac => mac.trim() !== ''))] : [];
    } else {
      // console.log('wb_mac 不包含逗号')
      wbMacList = [wb_mac]
    }
    // **3. 插入缺失的 gateway 设备**
    if (gwMacList.length > 0) {
      const existingGateways = await this.gatewayRepo.find({
        where: gwMacList.map(mac => ({ mac })),
      });
      // console.log('existingGateways', existingGateways)
      const existingGwMacs = new Set(existingGateways.map(g => g.mac));
      // console.log('existingGwMacs', existingGwMacs)
      // console.log('existingGwMacs', !!!existingGwMacs.has('30:ed:a0:27:33:50'))
      const newGateways = gwMacList
        .filter(mac => !existingGwMacs.has(mac))
        .map(mac => ({ mac }));
      // console.log('newGateways', newGateways)
      if (newGateways.length > 0) {
        try {
          await this.gatewayRepo.insert(newGateways);
        } catch (err) {
          // 跳过（存在的部分）
        }
      }
    }

    // **4. 插入缺失的 wristband 设备**
    if (wbMacList.length > 0) {
      const existingWristbands = await this.wristbandRepo.find({
        where: wbMacList.map(mac => ({ mac })),
      });
      const existingWbMacs = new Set(existingWristbands.map(w => w.mac));

      const newWristbands = wbMacList
        .filter(mac => !existingWbMacs.has(mac))
        .map(mac => ({ mac }));

      if (newWristbands.length > 0) {
        try {
          await this.wristbandRepo.insert(newWristbands);
        } catch (err) {
          // 跳过（存在的部分）
        }
      }
    }
    // console.log("测试时")
    // console.log(gw_full, wb_full)

    // **5. 检查是否已存在相同 taskid 的记录**
    const existingTask = id ? await this.otaTask.findOne({ where: { id } }) : null;

    // **6. 创建新记录（继承 existingTask.time 或使用当前时间）**
    const log = new OtaTask();
    log.id = id || uuidv4();
    log.firmwareid = firmwareIdStr;
    log.firmwareid_1 = firmwareId1Str;
    log.gw_mac = gwMacList.length > 0 ? gwMacList.join(',') : null;
    log.wb_mac = wbMacList.length > 0 ? wbMacList.join(',') : null;
    log.full = !!full;
    log.gw_full = !!gw_full;
    log.wb_full = !!wb_full;
    log.force = !!force; // 强制更新
    log.remain = !!remain; // 长期更新
    log.path = path;
    log.time = existingTask?.time || new Date(); // 继承 existingTask.time，否则用当前时间
    log.updateTime = new Date(); // 新记录的更新时间设为当前时间
    log.updateMode = updateMode; // 升级方式
    log.duration = duration || null; // 手环升级时长
    log.wb_count = wb_count || null; // 手环数量
    log.deleted = false;

    console.log('log', log)
    // **7. 保存到数据库**
    await this.otaTask.save(log);
    // console.log(savedLog);
  }


  async findGateWay(gw) {
    if (!gw?.gw_mac) return; // 为空时直接返回
    const existingGateway = await this.gatewayRepo.findOne({ where: { mac: gw.gw_mac } });
    if (!existingGateway) {
      // Insert if the gateway does not exist
      // time: gw.time
      await this.gatewayRepo.insert(
        {
          mac: gw.gw_mac,
          version_bin: gw.version_bin,
          version_fs: gw.version_fs,
          time: new Date(),
          deleted: false,
          last_report_time: new Date(), // 最后上报广播数据的时间
          reg_time: new Date(), // 入网时间
          last_report_wb_cnt: gw.last_report_wb_cnt // 最后上报手环数据
        });
    } else {
      // Update if the gateway already exists
      // time: gw.time
      // console.log('gw',gw)
      try {
        let obj = {
          mac: gw.gw_mac,
          version_bin: gw.version_bin,
          version_fs: gw.version_fs,
          time: new Date(),
          last_report_time: new Date(), // 最后上报广播数据的时间
          last_report_wb_cnt: gw.last_report_wb_cnt, // 最后上报手环数据
          outdoor: false, // 默认室内
        }
        // console.log('obj', obj)
        await this.gatewayRepo.update(
          { mac: gw.gw_mac }, obj);

      } catch (err) {
        console.log(err)
      }

    }
  }




  async findWristBand(gw_mac, wbMacList) {
    if (wbMacList.length === 0) return;
    // 1. 查询数据库中已有的手环
    const existingWristbands = await this.wristbandRepo.find({
      where: wbMacList.map(mac => ({ mac: mac.addr })),
    });
    const existingWbMacs = new Set(existingWristbands.map(g => g.mac));
    // 2. 处理新手环  time: gw.time
    const newWristbands = wbMacList
      .filter(mac => !existingWbMacs.has(mac.addr))
      .map(mac => ({
        id: uuidv4(),
        mac: mac.addr,
        time: new Date(),
        fw_name: mac.name,
        fw_version: mac.version,
        deleted: 0,
      }));

    if (newWristbands.length > 0) {
      await this.wristbandRepo.insert(newWristbands);
    }
    // 3. 处理需要更新的手环 time: gw.time
    const updates = wbMacList
      .filter(mac => existingWbMacs.has(mac.addr))
      .map(mac => ({
        mac: mac.addr,
        fw_name: mac.name,
        fw_version: mac.version,
        time: new Date(),
        deleted: 0,
      }));
    if (updates.length > 0) {
      await Promise.all(
        updates.map(async update => {
          await this.wristbandRepo.update({ mac: update.mac }, update);
        })
      );
    }
    // // 4. 查询现有的 gw_mac 对应的手环列表
    // const existingGwRecord = await this.gatewayWristbandRepo.findOne({ where: { gw_mac } });
    // const existingWbMacsInGw = existingGwRecord?.wb_mac ? existingGwRecord.wb_mac.split(',') : [];

    // // 5. 合并去重
    // const newWbMacs = Array.from(new Set([...existingWbMacsInGw, ...wbMacList.map(mac => mac.addr)]));
    // const wbMacsString = newWbMacs.join(',');

    // // 6. 更新或插入记录
    // if (existingGwRecord) {
    //   await this.gatewayWristbandRepo.update({ gw_mac }, { wb_mac: wbMacsString });
    // } else {
    //   await this.gatewayWristbandRepo.insert({ gw_mac, wb_mac: wbMacsString });
    // }
  }

  // // 计算升级进度（根据action logs）
  // private calculateUpgradeProgress(actionLogs: ActionLogOta[]) {
  //   if (!actionLogs || actionLogs.length === 0) {
  //     return {
  //       status: '未开始',
  //       progress: 0,
  //       lastAction: null,
  //       lastUpdate: null
  //     };
  //   }

  //   // 获取最后一条记录
  //   const lastAction = actionLogs[actionLogs.length - 1];

  //   // 根据action类型判断状态
  //   let status = '进行中';
  //   let progress = 0;

  //   switch (lastAction.action) {
  //     case action_enum.START:
  //       progress = 10;
  //       break;
  //     case action_enum.FLASH:
  //       progress = 50;
  //       break;
  //     case action_enum.SUCCESS:
  //       status = '已完成';
  //       progress = 100;
  //       break;
  //     case action_enum.ERROR:
  //       status = '失败';
  //       progress = 0;
  //       break;
  //     default:
  //       progress = 0;
  //   }

  //   return {
  //     status,
  //     progress,
  //     lastAction: lastAction.action,
  //     lastUpdate: lastAction.time,
  //     logs: actionLogs // 可选：包含所有日志详情
  //   };
  // }


  // **获取所有 OTA 任务**
  // 获取所有OTA任务（包含准确的升级进度统计）
  async getAllOtaTasks(params) {
    console.log('otaTask params', params)
    const { firmwareid, firmware, wb_mac, gw_mac, pageNum, pageSize } = params;

    // 1. 构建主查询（OTA任务列表）
    const query = this.otaTask.createQueryBuilder('otaTask')
      .leftJoinAndSelect('otaTask.firmware', 'firmware')
      .leftJoinAndSelect('otaTask.firmware1', 'firmware1')
      .leftJoinAndSelect('firmware.file', 'file')
      .leftJoinAndSelect('firmware1.file', 'file1')
      .orderBy('otaTask.time', "DESC")
      .where('otaTask.deleted != :deleted', { deleted: true });

    // 添加查询条件
    if (firmwareid) query.andWhere('otaTask.firmwareid = :firmwareid', { firmwareid });
    if (wb_mac) query.andWhere('otaTask.wb_mac = :wb_mac', { wb_mac });
    if (gw_mac) query.andWhere('otaTask.gw_mac = :gw_mac', { gw_mac });
    // 如果传的是 firmware, 需要根据 firmware 或 firmware1 进行模糊查询 对应的 firmwareType
    if (firmware) {
      query.andWhere('firmware.firmwareType LIKE :firmware OR firmware1.firmwareType LIKE :firmware', { firmware: `%${firmware}%` });
    }

    // 分页处理
    if (pageNum && pageSize) {
      query.skip((pageNum - 1) * pageSize).take(pageSize);
    }

    const total = await query.getCount();
    const tasks = await query.getMany();

    // // 2. 批量查询每个任务的相关数据
    // const taskIds = tasks.map(task => task.id);

    // // 获取每个任务分配的手环总数（去重）
    // const assignedWbCounts = await this.getAssignedWbCounts(taskIds);

    // // 获取每个任务已升级成功的手环数（去重）
    // const upgradedWbCounts = await this.getUpgradedWbCounts(taskIds);

    // // 3. 构建返回数据
    // const taskWithProgress = await Promise.all(
    //   tasks.map(async (task) => {
    //     const actionLogs = await this.actionLogOtaRepository.find({
    //       where: { taskid: task.id },
    //       order: { time: 'ASC' }
    //     });

    //     // 计算进度
    //     const totalAssigned = assignedWbCounts[task.id] || 0;
    //     const totalUpgraded = upgradedWbCounts[task.id] || 0;
    //     const progress = totalAssigned > 0
    //       ? Math.round((totalUpgraded / totalAssigned) * 100)
    //       : 0;

    //     return {
    //       ...task,
    //       progress: {
    //         status: progress === 100 ? '已完成' : progress > 0 ? '进行中' : '未开始',
    //         progress,
    //         totalAssigned, // 分配的手环总数
    //         totalUpgraded, // 已升级的手环数
    //         lastUpdate: actionLogs.length > 0 ? actionLogs[actionLogs.length - 1].time : null
    //       }
    //     };
    //   })
    // );

    // 4. 返回结果
    return {
      total,
      // data: taskWithProgress,
      data: tasks
    };
  }

  // // 获取每个任务分配的手环总数（处理逗号分隔的wb_mac）
  // private async getAssignedWbCounts(taskIds: string[]) {
  //   if (taskIds.length === 0) return {};

  //   // 1. 先获取所有相关任务的数据
  //   const tasks = await this.otaTask.createQueryBuilder('task')
  //     .select(['task.id', 'task.wb_mac'])
  //     .where('task.id IN (:...taskIds)', { taskIds })
  //     .getMany();
  //   // 2. 处理每个任务的wb_mac（拆分成数组并去重）
  //   const result = {};
  //   tasks.forEach(task => {
  //     if (!task.wb_mac) {
  //       result[task.id] = 0;
  //       return;
  //     }
  //     // 拆分逗号分隔的字符串，并去重
  //     const macs = task.wb_mac.split(',')
  //       .map(mac => mac.trim())
  //       .filter(mac => mac.length > 0)
  //       .map(fullMac => {
  //         // 提取MAC地址前5段（去掉最后一部分）
  //         const parts = fullMac.split(':');
  //         if (parts.length === 6) {
  //           return parts.slice(0, 5).join(':');
  //         }
  //         return fullMac; // 如果不是标准MAC格式，保留原样
  //       });
  //     const uniqueMacs = [...new Set(macs)];
  //     result[task.id] = uniqueMacs.length;
  //   });
  //   return result;
  // }

  // // 获取每个任务已升级成功的手环数（去重）
  // private async getUpgradedWbCounts(taskIds: string[]) {
  //   if (taskIds.length === 0) return {};

  //   const result = await this.actionLogOtaRepository.createQueryBuilder('log')
  //     .select('log.taskid', 'taskId')
  //     .addSelect('COUNT(DISTINCT log.wb_mac)', 'wbCount')
  //     .where('log.taskid IN (:...taskIds)', { taskIds })
  //     .andWhere('log.action = :action', { action: action_enum.SUCCESS })
  //     .groupBy('log.taskid')
  //     .getRawMany();

  //   return result.reduce((acc, curr) => {
  //     acc[curr.taskId] = parseInt(curr.wbCount);
  //     return acc;
  //   }, {});
  // }


  // **根据 ID 获取 OTA 操作日志**
  async getOta_TaskById(id: string) {
    try {
      const result = await this.otaTask.findOne({ where: { id } });
      console.log('result', result)
      if (result) {
        return result;
      }
    } catch (err) {
      console.log('err', err)
    }

  }

  // **根据网关和手环 MAC 获取 OTA 操作日志**
  async getOtaTaskByGwAndWb(gw_mac: string, wb_mac: string) {
    return await this.otaTask.find({
      where: { gw_mac, wb_mac },
      order: { time: 'DESC' },
    });
  }

  // **更新 OTA 操作日志**
  async updateOtaTask(id: string, updateData: Partial<OtaTask>) {
    const log = await this.getOta_TaskById(id);
    if (!log) return null;
    log.updateTime = new Date();

    Object.assign(log, updateData);
    return await this.otaTask.save(log);
  }

  // **删除 OTA 操作日志**
  async deleteOtaTask(id: string) {
    // console.log('id...',id)
    let ota_task;
    try {
      ota_task = await this.getOta_TaskById(id);
    } catch (err) {
      console.log('ota_task 有误', err)
    }
    // 判断该id存不存在
    if (!ota_task) return resBuild.fail('固件不存在！');
    ota_task.updateTime = new Date(); // 更新修改时间
    await this.otaTask.update({ id: id }, { deleted: true });
    return resBuild.success();
  }
}
